

#define NDEBUGxx

#include "HIDProx.h"
#include "rfid_common.h"
#include "rfid_interface.h"
#include "utility.h"
#include "Debug.h"
#include "Log.h"
#include <string.h>
#include <Utility/BitSlider.h>

#if RFID_ITF_HID_CARD_EN

static hid_card_t hid_card;

static int get_uid(uint8_t *bit_data, uint8_t uid[5], uint8_t type);
static int check_data(uint8_t *bit_data, uint8_t type);
static uint8_t get_card_type(uint8_t *bit_data);

static void print_bits(const uint8_t* bits, uint32_t len){
#ifndef NDEBUG
	LOG("bits:");
	for(uint32_t i = 0; i < len; i++){
		LOG("%d", bits[i]);
	}
	LOG("\n");
#endif 
}

static void print_bit_buf(const BitBuf_T* bitbuf){
#ifndef NDEBUG
	LOG("bits: ");
	for(uint32_t i = 0; i < bitbuf->num_bits; i++){
		int val;
//		BitBuf_TestBit(bitbuf, i, &val);
		LOG("%d", val);
	}
	LOG("\n");
#endif 
}

static int hid_card_do_get_info(hid_card_t *card, hid_card_info_t *info){
	int ret;
	FSKDecoder_T* decoder = &card->decoder;
	uint8_t *data = decoder->dataBuf;
	ret = get_card_type(data);//获取数据类型
	if(ret == 0xFF){
		return 6;
	}	
	info->type = ret;
	ret = check_data(data, info->type);
	if(ret != 0){
		if(ret < 0)//校验数据
		{
			return 2;
		}
		if(info->type != 34){
			return 3;
		}
		if(ret != 2){
			//前半部分校验错误
			return 4;
		}
		//后半部分校验错误
		ret = 1;
	}
	//获取卡号
	if(get_uid(data, info->uid, info->type)){
		//无效卡号
		ret = 5;
	}
	
	return ret;
}

////////

static int hid_card_manchester_decode(uint32_t bits, uint32_t size, uint32_t* data){
	uint32_t idx = 0;
	uint32_t d = 0;
	
	if(size < 2 || size & 1){
		TRACE_E("size= %d", size);
		return -1;
	}
	
	*data = 0;
	
	do{
		uint32_t c = (bits >> idx) & 0x03;
		if(c == 0x01){
			//由高到低
			d |= 1;
		}
		else
		if(c == 0x02){
			//由低到高
			//d |= 0;
		}
		else{
			TRACE_E("c=%X", c);
			return -2;
		}
		d <<= 1;
		idx += 2;
	}while(idx < size);
	
	*data = d;
	return 0;
}

static int hid_card_search_sof(BitBuf_T* bitbuf, uint32_t* bit){
	return -1;
}

//获取类型码
static int hid_card_get_custome_code(BitBuf_T* bitbuf, uint32_t* bit, uint8_t* code){
	//类型码7bit,每个bit两个曼彻斯特电平。
	const uint8_t codeSize = 7 * 2;
	BitBundle_T bitbundle;
	
	memset(&bitbundle, 0, sizeof(bitbundle));
	bitbundle.num = codeSize;
	*code = 0;
	int num = BitBuf_GetBundle(bitbuf, *bit, &bitbundle);
	if(num < 1){
		TRACE_E("no bits!");
		return -1;
	}
	
	*bit += num;
	if(num != codeSize){
		TRACE_E("no enough bits!");
		return -2;
	}
	uint32_t data;
	int ret = hid_card_manchester_decode(bitbundle.bundle, bitbundle.off, &data);
	if(ret){
		return ret;
	}
	*code = data;
	return ret;
}

static int hid_card_prase_data(BitBuf_T* bitbuf, uint32_t* bit, uint8_t custome, hid_card_info_t* info){
	return -1;
}

static int hid_card_get_data(BitBuf_T* bitbuf, uint32_t* bit, hid_card_info_t* info){
	uint8_t custome;
	int ret = hid_card_get_custome_code(bitbuf, bit, &custome);
	if(ret){
		return ret;
	}
	TRACE_I("custome=%d", custome);
	return hid_card_prase_data(bitbuf, bit, custome, info);
}

int hid_card_decode(BitBuf_T* bitbuf, hid_card_info_t* info){
	int ret;
	uint32_t bit = 0;
	
	while(1){
		ret = hid_card_get_data(bitbuf, &bit, info);
		if(!ret){
			return ret;
		}
		
		ret = hid_card_search_sof(bitbuf, &bit);
		if(ret){
			break;
		}
	}
	return -1;
}

int hid_card_get(hid_card_info_t *info)
{
	int ret = -1;
	FSKDecoder_T* decoder = &hid_card.decoder;
	
	if(decoder->done)
	{
		LOG_DBG("hid_card_get ");
		print_bit_buf(&decoder->manchesterBit);
		ret = hid_card_decode(&decoder->manchesterBit, info);
		decoder->done = 0;
	}
	return ret;
}

#if 0
int hid_card_get(hid_card_info_t *info)
{
	int ret = -1;
	FSKDecoder_T* decoder = &hid_card.decoder;
	
	if(decoder->done)
	{
		LOG_D("hid_card_get ");
		print_bits(decoder->dataBuf, decoder->dataLength);
		ret = hid_card_do_get_info(&hid_card, info);
		decoder->done = 0;
	}
	return ret;
}
#endif 

#if 0
void hid_card_init(void){
	memset(&hid_card, 0, sizeof(hid_card));
	hid_card.decoder.header = (uint8_t)~0;
}
#endif 

static void hid_card_frame_init(HidFrame_T* frame){
	BitSlider_Init(&frame->bits, frame->container, sizeof(frame->container)/sizeof(frame->container[0]), 0);
	frame->type = HID_FRAME_None;
}

static void hid_card_complete(BitSlider_T* bits){

}

static inline int FSKDecoder_PeriodLevel(const uint8_t period){
	if((FSK_Long_Period - 2) <= period && period <= (FSK_Long_Period + 3 )){
		//低频->高电平
		return 1;
	}
	else
	if((FSK_Short_Period - 4) < period && period < (FSK_Short_Period + 2)){
		//高频->低电平
		return 0;
	}
	
	return -1;
}


static BitSlider_T hidLevelBits;

static FSKDecoderParams_T hidDecoderParam = {
	.complete = hid_card_complete,
	.longPeriodRange[2] = {FSK_Long_Period - 2, FSK_Long_Period + 3},		//低频有效范围
	.shortPeriodRange[2] = {FSK_Short_Period - 3, FSK_Short_Period + 1},	//高频有效范围
	.periodShort = FSK_Short_Period,	//短周期
	.periodLong = FSK_Long_Period,		//长周期
	.header_init = 0xFF,	//sof初始值
	.sync = HID_CARD_HEADER_VALUE,		//sof值
	.levelBits = &hidLevelBits,	//电平缓存
	.levelNum = HID_CARD_LONG_FRAME_SIZE - 8,		//期望接收的长度
	.lowNum = 5,			//低电平位宽
	.highNum = 6,			//高电平位宽
};

void hid_card_init(void){
	FSKDecoder_Init(&hid_card.decoder, &hidDecoderParam);
	hid_card_frame_init(&hid_card.frameBackup);
	BitSlider_Init(&hid_card.output, hid_card.outputBuffer, sizeof(hid_card.outputBuffer)/sizeof(hid_card.outputBuffer[0]), 0);
}


//HID卡数据解析,在ADC-DMA半中断以及满中断进行调用
//参数：采集的ADC值, 数据长度
void hid_card_data_decode(uint16_t *value, uint32_t len)
{
	FSKDecoder_T* decoder = &hid_card.decoder;
	FSKDecoder_Decode(decoder, value, len);
}

static uint8_t get_card_type(uint8_t *bit_data)
{
	uint8_t type[3] = {0}, card_type;
	for(int x=0;x<3;x++)
	{
		for(int y=0;y<8;y++)
		{
			type[x] <<= 1;
			type[x] |= bit_data[(x * 8) + y];
		}
	}
	
	if(!(type[0] & 0xFC))
	{
		if(!(type[0]&0x02)) card_type = 37;
		else if(type[0] & 0x01) card_type = 36;
		else if(type[1] & 0x80) card_type = 35;
		else if(type[1] & 0x40) card_type = 34;
		else if(type[1] & 0x20) card_type = 33;
		else if(type[1] & 0x10) card_type = 32;
		else if(type[1] & 0x08) card_type = 31;
		else if(type[1] & 0x04) card_type = 30;
		else if(type[1] & 0x02) card_type = 29;
		else if(type[1] & 0x01) card_type = 28;
		else if(type[2] & 0x80) card_type = 27;
		else  card_type = 26;
	}
	else  card_type = 0xFF;
	
	return card_type;
}

static int check_data(uint8_t *bit_data, uint8_t type)
{
	uint8_t check;
	uint8_t *ptr = &bit_data[44 - type];
	uint8_t op_start, op_end, ep_start;
	
	switch(type)
	{
		case 26: op_start = 0; op_end = 13; ep_start = 13; break;
		case 27: op_start = 1; op_end = 13; ep_start = 13; break;//未测试
		case 34: op_start = 0; op_end = 17; ep_start = 17; break;
		case 35: op_start = 1; op_end = 17; ep_start = 17; break;//未测试
		case 36: op_start = 0; op_end = 18; ep_start = 18; break;//未测试
		case 37: op_start = 0; op_end = 19; ep_start = 18; break;
		
		default :return -1;
	}
	LOG_D("check_data ");
	print_bits(ptr, type);
	check = 0;
	for(int i=op_start;i<op_end;i++) check ^= ptr[i];
	if(check)
		return 1;
	
	check = 0;
	for(int i=ep_start;i<type;i++) check ^= ptr[i];
	if(check != 1)
		return 2;
	
	return 0;
}

static int get_uid(uint8_t *bit_data, uint8_t uid[5], uint8_t type)
{
	uint64_t uid64 = 0;
	for(uint8_t i=0;i<type;i++)
	{
		uid64 <<= 1;
		uid64 |= bit_data[44 - type + i];
	}
	if(!uid64){
		//卡号为0，无效
		return -1;
	}
	memcpy(uid, &uid64, 5);
	reverse_data(uid, 5);
	return 0;
}

#if 0
//HID卡数据解析,在ADC-DMA半中断以及满中断进行调用
//参数：采集的ADC值, 数据长度
void hid_card_data_decode(uint16_t *value, uint32_t len)
{
	uint32_t pt_number = load_period_time(value, len);//装载周期时间
	smooth_time_data(hid_card.period_time, pt_number);//周期时间数据的平滑处理
	uint32_t bit_number = period_time_to_bit_data(hid_card.period_time, pt_number, hid_card.bit_data, sizeof(hid_card.bit_data));//周期时间转换为数据位
	int data_index = find_hrader(hid_card.bit_data, bit_number);//根据位数据解析引导头
	decode_data(data_index, hid_card.bit_data, bit_number);//数据解析
}

static void decode_data(uint32_t data_index, uint8_t *bit_data, uint32_t bit_number)
{
	static uint8_t manchester_bit[2], manchester_bit_cnt = 0;
	
	if(hid_card.header != HID_CARD_HEADER_VALUE)
	{
		manchester_bit_cnt = 0;
		return ;
	}
	
	//解析曼切斯特数据
	for(uint32_t i=data_index;i<bit_number;i++)
	{
		manchester_bit[manchester_bit_cnt++] = bit_data[i];
		
		if(manchester_bit_cnt >= 2)
		{
			manchester_bit_cnt = 0;
			
			if(manchester_bit[0] == 0 && manchester_bit[1] == 1)
				hid_card.man_bit_data[hid_card.man_bit_index] = 0;
			else if(manchester_bit[0] == 1 && manchester_bit[1] == 0)
				hid_card.man_bit_data[hid_card.man_bit_index] = 1;
			else //数据错误
			{
				hid_card.man_bit_index = 0;
				hid_card.header = 0;
				break;
			}
			
			hid_card.man_bit_index ++;
			
			if(hid_card.man_bit_index >= sizeof(hid_card.man_bit_data))//完成数据读取
			{
				if(hid_card.recv_done == 0)
				{
					memcpy(hid_card.data, hid_card.man_bit_data, sizeof(hid_card.data));
					hid_card.recv_done = 1;
				}
				hid_card.header = 0;
				hid_card.man_bit_index = 0;
			}
		}
	}
}

//寻找引导头
static int find_hrader(uint8_t *bit_data, uint32_t bit_number)
{
	if(hid_card.header == HID_CARD_HEADER_VALUE) return 0;
	for(uint32_t i=0;i<bit_number;i++)
	{
		hid_card.header <<= 1;
		hid_card.header |= hid_card.bit_data[i] ? 0x01 : 0x00;
		if(hid_card.header == HID_CARD_HEADER_VALUE) {
			return i + 1;
		}
	}
	return -1;
}

//周期时间转换成位数据
//返回值：位数量
static uint32_t period_time_to_bit_data(uint8_t *period_time, uint32_t number, uint8_t *bit_data, uint32_t size)
{
	static uint8_t hlevel_keeptime = 0, llevel_keeptime = 0;
	uint8_t level = compute_average_time_value(period_time, number);
	uint32_t bit_index = 0;
	
	for(uint32_t i = 0; i<number; i++)
	{
		#define bit_data_write(x)		if(bit_index < size)\
											bit_data[bit_index ++] = x;

		if(period_time[i] <= level)//高频
		{
			if(hlevel_keeptime >= 4) bit_data_write(1);//若低电平保持时间快要达到则算一个位
			llevel_keeptime ++;
			hlevel_keeptime = 0;
			if(llevel_keeptime >= 6)
			{
				llevel_keeptime = 0;
				bit_data_write(0);
			}
		}
		else
		{
			if(llevel_keeptime >= 5) bit_data_write(0);
			hlevel_keeptime ++;
			llevel_keeptime = 0;
			if(hlevel_keeptime >= 5)
			{
				hlevel_keeptime = 0;
				bit_data_write(1);
			}
		}
	}
	
	return bit_index;
}

static void print_bits(const uint8_t* bits, uint32_t len){
#ifndef NDEBUG
	LOG_D("bits:");
	for(uint32_t i = 0; i < len; i++){
		LOG("%d", bits[i]);
	}
	LOG("\n");
#endif 
}

static uint8_t get_card_type(uint8_t *bit_data)
{
	uint8_t type[3] = {0}, card_type;
	for(int x=0;x<3;x++)
	{
		for(int y=0;y<8;y++)
		{
			type[x] <<= 1;
			type[x] |= bit_data[(x * 8) + y];
		}
	}
	
	if(!(type[0] & 0xFC))
	{
		if(!(type[0]&0x02)) card_type = 37;
		else if(type[0] & 0x01) card_type = 36;
		else if(type[1] & 0x80) card_type = 35;
		else if(type[1] & 0x40) card_type = 34;
		else if(type[1] & 0x20) card_type = 33;
		else if(type[1] & 0x10) card_type = 32;
		else if(type[1] & 0x08) card_type = 31;
		else if(type[1] & 0x04) card_type = 30;
		else if(type[1] & 0x02) card_type = 29;
		else if(type[1] & 0x01) card_type = 28;
		else if(type[2] & 0x80) card_type = 27;
		else  card_type = 26;
	}
	else  card_type = 0xFF;
	
	return card_type;
}


static int check_data(uint8_t *bit_data, uint8_t type)
{
	uint8_t check;
	uint8_t *ptr = &bit_data[44 - type];
	uint8_t op_start, op_end, ep_start;
	
	switch(type)
	{
		case 26: op_start = 0; op_end = 13; ep_start = 13; break;
		case 27: op_start = 1; op_end = 13; ep_start = 13; break;//未测试
		case 34: op_start = 0; op_end = 17; ep_start = 17; break;
		case 35: op_start = 1; op_end = 17; ep_start = 17; break;//未测试
		case 36: op_start = 0; op_end = 18; ep_start = 18; break;//未测试
		case 37: op_start = 0; op_end = 19; ep_start = 18; break;
		
		default :return -1;
	}
	LOG_D("check_data ");
	print_bits(ptr, type);
	check = 0;
	for(int i=op_start;i<op_end;i++) check ^= ptr[i];
	if(check)
		return 1;
	
	check = 0;
	for(int i=ep_start;i<type;i++) check ^= ptr[i];
	if(check != 1)
		return 2;
	
	return 0;
}

static int get_uid(uint8_t *bit_data, uint8_t uid[5], uint8_t type)
{
	uint64_t uid64 = 0;
	for(uint8_t i=0;i<type;i++)
	{
		uid64 <<= 1;
		uid64 |= bit_data[44 - type + i];
	}
	if(!uid64){
		//卡号为0，无效
		return -1;
	}
	memcpy(uid, &uid64, 5);
	reverse_data(uid, 5);
	return 0;
}

static uint32_t load_period_time(uint16_t *value, uint32_t len)
{
	static uint8_t period_adc_cnt = 0;
	uint32_t central_value = compute_average_adc_value(value, len);//计算电压中心值
	uint32_t index = 0, time_index = 0;
	memset(hid_card.period_time, 0, sizeof(hid_card.period_time));
	if(period_adc_cnt & 0x80) goto read_low_level;//上次读取到低电平
	while(len)
	{
		while(value[index] >= central_value)//高电平
		{
			period_adc_cnt ++;
			index++;
			if(index >= len) break;
		}
		if(index >= len) break;
		period_adc_cnt |= 0x80;
		
		read_low_level:
		
		while(value[index] < central_value)//低电平
		{
			period_adc_cnt ++;
			index++;
			if(index >= len) break;
		}
		if(index >= len) break;
		
		hid_card.period_time[time_index ++] = period_adc_cnt & 0x7F;
		period_adc_cnt = 0;
		if(time_index >= sizeof(hid_card.period_time)) break;
	}
	return time_index;
}

static void smooth_time_data (uint8_t *time, uint32_t len)
{
	uint8_t level = compute_average_time_value(time, len);
	for(uint32_t i=0;i<len;i+=2)
	{
		uint32_t before = time[i];
		uint32_t after = time[i+1];
		if(((before <= level) && (after <= level)) || ((before > level) && (after > level)))
		{
			time[i+1] = (before + after) / 2;
		}
	}
}
#endif 

#endif
